package com.ctsi.ssdc.admin.service.impl;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ctsi.ssdc.criteria.IntegerCriteria;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ctsi.ssdc.admin.domain.CscpMenus;
import com.ctsi.ssdc.admin.domain.CscpMenusExample;
import com.ctsi.ssdc.admin.domain.CscpMenusExample.Criteria;
import com.ctsi.ssdc.admin.domain.CscpRoleMenu;
import com.ctsi.ssdc.admin.domain.CscpRoleMenuExample;
import com.ctsi.ssdc.admin.domain.dto.CscpMenusCriteria;
import com.ctsi.ssdc.admin.domain.dto.CscpMenusDTO;
import com.ctsi.ssdc.admin.repository.CscpMenusRepository;
import com.ctsi.ssdc.admin.repository.CscpRoleMenuRepository;
import com.ctsi.ssdc.admin.service.CscpMenusService;
import com.ctsi.ssdc.admin.service.mapper.CscpMenusMapper;
import com.ctsi.ssdc.criteria.StringCriteria;
import com.ctsi.ssdc.model.MenuItemBean;
import com.ctsi.ssdc.model.PageResult;
import com.github.pagehelper.PageHelper;

/**
 * Service Implementation for managing CscpMenus.
 *
 * @author ctsi biyi generator
 *
 */
@Service
public class CscpMenusServiceImpl implements CscpMenusService {
    private final Logger log = LoggerFactory.getLogger(CscpMenusServiceImpl.class);

    @Autowired
    private CscpMenusRepository cscpMenusRepository;

    private final CscpMenusMapper cscpMenusMapper;
    
    @Autowired
    private CscpRoleMenuRepository cscpRoleMenuRepository;

    public CscpMenusServiceImpl(CscpMenusMapper cscpMenusMapper) {
        this.cscpMenusMapper = cscpMenusMapper;
    }

    /**
     * insert a cscpMenus.
     *
     * @param cscpMenusDTO the entity to insert
     * @return the persisted entity
     */

   /* public CscpMenusDTO insert(CscpMenusDTO cscpMenusDTO) {
        log.debug("Request to insert CscpMenus : {}", cscpMenusDTO);
        
        CscpMenus cscpMenus = cscpMenusMapper.toEntity(cscpMenusDTO);
        cscpMenusRepository.insert(cscpMenus);
        int id = cscpMenus.getId();
        CscpMenus  cscpMenusOrder = new CscpMenus();
        cscpMenusOrder.setOrderby(id);
        CscpMenusExample menusExample =new CscpMenusExample();
        Criteria criteria = menusExample.createCriteria();
        criteria.andIdEqualTo(id);
        cscpMenusRepository.updateByExampleSelective(cscpMenusOrder,menusExample);
        return cscpMenusMapper.toDto(cscpMenus);
    }*/
    @Override
    //重写insert方法
    public CscpMenusDTO insert(CscpMenusDTO cscpMenusDTO) {
        log.debug("Request to insert CscpMenus : {}", cscpMenusDTO);
        CscpMenus cscpMenus = cscpMenusMapper.toEntity(cscpMenusDTO);
        //获取orderby顺序
        cscpMenus.setOrderby(getOrderBy(cscpMenusDTO));
        cscpMenusRepository.insert(cscpMenus);
        return cscpMenusMapper.toDto(cscpMenus);
    }

    //获取orderby顺序
    @Override
    public int getOrderBy(CscpMenusDTO cscpMenusDTO){
        CscpMenus cscpMenus = cscpMenusMapper.toEntity(cscpMenusDTO);
        int orderById;
        int parent_id = cscpMenus.getParentId();
        //获取相同parent_id的孩子数量
        List<CscpMenus> childs = cscpMenusRepository.selectByParentId(parent_id);
        if (childs.isEmpty()){
            orderById = 1;
        }else{
            //最后一个孩子的顺序值
            orderById = childs.get(childs.size()-1).getOrderby()+1;
        }

        return orderById;
    }
     /**
     * update a cscpMenus.
     *
     * @param cscpMenusDTO the entity to update
     * @return the persisted entity
     */
    @Override
    public CscpMenusDTO update(CscpMenusDTO cscpMenusDTO) {
        log.debug("Request to update CscpMenus : {}", cscpMenusDTO);
        
        CscpMenus cscpMenus = cscpMenusMapper.toEntity(cscpMenusDTO);
        cscpMenusRepository.updateByPrimaryKeySelective(cscpMenus);
        return cscpMenusMapper.toDto(cscpMenus);
    }
    
    

    /**
     * Get all the cscpMenuss.
     *
     * @return the list of entities
     */
    @Override
    @Transactional(readOnly = true)
    public PageResult<CscpMenusDTO> findAll() {
        log.debug("Request to get all CscpMenuss");
        
        List<CscpMenusDTO> data = cscpMenusRepository.selectByExample(null).stream()
                .map(cscpMenusMapper::toDto)
                .collect(Collectors.toCollection(LinkedList::new));
                
        long count = 0L;
		
		if(CollectionUtils.isNotEmpty(data)) {
			count = cscpMenusRepository.countByExample(null);
		}
		
		return new PageResult<CscpMenusDTO>(data,count,count);        
        
    }

    @Override
    public List<CscpMenus> findAllList() {
        log.debug("Request to get all CscpMenuss");
        return cscpMenusRepository.selectByExample(null);
    }
    /**
     * Get one cscpMenus.
     *
     * @param id the id of the entity
     * @return the entity
     */
    @Override
    @Transactional(readOnly = true)
    public CscpMenusDTO findOne(Integer id) {
        log.debug("Request to get CscpMenus : {} ", id);
        
        CscpMenus cscpMenus = cscpMenusRepository.selectByPrimaryKey(id);
        return cscpMenusMapper.toDto(cscpMenus);
    }

    /**
     * Delete the cscpMenus .
     *递归删除节点下面所有子节点
     * @param id the id of the entity
     */
    @Override
    public void delete(Integer id) {
        log.debug("Request to delete CscpMenus : {} ", id);
        List<CscpMenus> cscpMenus = cscpMenusRepository.selectByParentId(id);
        if(!cscpMenus.isEmpty()){
            for(CscpMenus cscpMenu:cscpMenus){
                delete(cscpMenu.getId());
            }
        }
        cscpMenusRepository.deleteByPrimaryKey(id);
    }
    
    private String getPageOrderBy(Pageable page) {
		
		if(page!= null && page.getSort() != null) {
			
			StringBuilder sb = new StringBuilder();
			
			page.getSort().forEach(sort -> sb.append(sort.getProperty())
					.append(" ").append(sort.getDirection()).append(","));
			
			if(sb.length() > 1) {
				return (sb.substring(0,sb.length()-1));
			}
		}
		
		return null;
	}
	
	/**
     * Get the cscpMenuss.
     *
     * @return the list of entities
     */
    @Override
    @Transactional(readOnly = true)
    public PageResult<CscpMenusDTO> findByCscpMenusDTO(CscpMenusDTO cscpMenusDTO, Pageable page) {
        
        log.debug("Request to find CscpMenuss");
        
    	CscpMenusExample example = new CscpMenusExample();
    	
    	example.setPage(page);
		
		Criteria critieria = example.createCriteria();
		
		if(cscpMenusDTO.getId() != null) {
			critieria.andIdEqualTo(cscpMenusDTO.getId());
		}		
		if(cscpMenusDTO.getParentId() != null) {
			critieria.andParentIdEqualTo(cscpMenusDTO.getParentId());
		}		
		if(cscpMenusDTO.getOrderby() != null) {
			critieria.andOrderbyEqualTo(cscpMenusDTO.getOrderby());
		}		

		if(StringUtils.isNotBlank(cscpMenusDTO.getName())) {
			critieria.andNameLike(String.format("%%%s%%", cscpMenusDTO.getName()));
		}		
		if(StringUtils.isNotBlank(cscpMenusDTO.getIcon())) {
			critieria.andIconLike(String.format("%%%s%%", cscpMenusDTO.getIcon()));
		}		
		if(StringUtils.isNotBlank(cscpMenusDTO.getTitle())) {
			critieria.andTitleLike(String.format("%%%s%%", cscpMenusDTO.getTitle()));
		}		
		if(StringUtils.isNotBlank(cscpMenusDTO.getUrl())) {
			critieria.andUrlLike(String.format("%%%s%%", cscpMenusDTO.getUrl()));
		}		
		if(StringUtils.isNotBlank(cscpMenusDTO.getComponent())) {
			critieria.andComponentLike(String.format("%%%s%%", cscpMenusDTO.getComponent()));
		}		
		if(StringUtils.isNotBlank(cscpMenusDTO.getType())) {
			critieria.andTypeLike(String.format("%%%s%%", cscpMenusDTO.getType()));
		}		
		
		String orderBy = getPageOrderBy(page);

		if(StringUtils.isNotEmpty(orderBy)) {
			example.setOrderByClause(orderBy);
		}
		PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		List<CscpMenusDTO> data = cscpMenusMapper.toDto(cscpMenusRepository.selectByExamplewithPage(example));
    
     	long count = 0L;
		
		if(CollectionUtils.isNotEmpty(data)) {
			count = cscpMenusRepository.countByExample(example);
		}
		
		return new PageResult<CscpMenusDTO>(data,count,count);       
		
    }
    
    /**
     * Get the cscpMenuss.
     *
     * @param cscpMenusCriteria
     * @param page
     * @return
     */
	public PageResult<CscpMenusDTO> findByCscpMenusCriteria(CscpMenusCriteria cscpMenusCriteria, Pageable page) {
	
		CscpMenusExample example = new CscpMenusExample();
    	
    	example.setPage(page);
		
		Criteria criteria = example.createCriteria();
		
		if(cscpMenusCriteria != null) {
			cscpMenusCriteria.buildCriteria(criteria);
		}		

		String orderBy = getPageOrderBy(page);

		if(StringUtils.isNotEmpty(orderBy)) {
			example.setOrderByClause(orderBy);
		}
		PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		List<CscpMenusDTO> data = cscpMenusMapper.toDto(cscpMenusRepository.selectByExamplewithPage(example));
		
		long count = 0L;
		
		if(CollectionUtils.isNotEmpty(data)) {
			count = cscpMenusRepository.countByExample(example);
		}
		
		return new PageResult<CscpMenusDTO>(data,count,count);    
		
	}

    @Override
    public List<CscpMenusDTO> findByUserId(Integer id) {
        return cscpMenusMapper.toDto(cscpMenusRepository.selectByUserId(id));
    }
    
    @Override
    public MenuItemBean roleMenuList(Integer roleId) {
        
        try {
        	Map<Integer, CscpMenusDTO> hasRight = cscpMenusRepository.menusByRole(roleId);
            List<CscpMenusDTO> allMenus = cscpMenusRepository.selectByExample(null).stream()
                    .map(cscpMenusMapper::toDto)
                    .collect(Collectors.toCollection(LinkedList::new));
            HashMap<String, MenuItemBean> itemMap = new HashMap<String, MenuItemBean>();
            List<MenuItemBean> list = new ArrayList<MenuItemBean>();
            for (int i = 0; i < allMenus.size(); i++) {
                MenuItemBean mib = new MenuItemBean();
                CscpMenusDTO item = allMenus.get(i);
                if (item.getType().equals("parent") || item.getUrl() == null) {//URL为空
                    mib.setHref("#");
                } else {
                    mib.setSref(item.getUrl());
                }
                mib.setTitle(item.getTitle());//TITILE
                mib.setIcon(item.getIcon());//ICON
                mib.setId(item.getId().toString());//ID
                if (hasRight.get(item.getId()) == null) {
                    mib.setChecked(false);
                } else {
                    mib.setChecked(true);
                }
                
                //mib.setPermissions(mapPermission.get(mib.getId()));
                mib.setHasPermission(mib.getPermissions()!=null);

                if (itemMap.get(item.getParentId().toString()) != null) {
                    MenuItemBean pmib = (MenuItemBean) itemMap.get(item.getParentId().toString());
                    List<MenuItemBean> subitem = (pmib).getItems();
                    if (subitem == null) {
                        subitem = new ArrayList<MenuItemBean>();
                        pmib.setItems(subitem);
                        pmib.setChecked(false);
                    }
                    subitem.add(mib);

                } else {
                    list.add(mib);
                }
                itemMap.put(item.getId().toString(), mib);
            }

            MenuItemBean example = new MenuItemBean();
            example.setItems(list);
            return example;
        } catch (Exception e) {
        	throw new RuntimeException(e);
        }
       
    }

	@Override
	@Transactional
	public void saveRoleMenus(Integer roleId, String menus, String permissions) {
		String[] ms = menus.split(",");

		try {
			CscpRoleMenuExample example = new CscpRoleMenuExample();
			IntegerCriteria roleIdCriteria = new IntegerCriteria();
			roleIdCriteria.setEquals(roleId);
			example.setRoleId(roleIdCriteria);
			example.buildCriteria();
			cscpRoleMenuRepository.deleteByExample(example);
			
			for (int i = 0; i < ms.length; i++) {
				CscpRoleMenu record = new CscpRoleMenu();
				record.setRoleId(roleId);
				record.setMenuId(Integer.valueOf(ms[i]));
				cscpRoleMenuRepository.insert(record);
			}

		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}
    //按照父id查找menus
    @Override
    public List<CscpMenus> findByParentId(Integer parentId) {
        return cscpMenusRepository.selectByParentId(parentId);
    }

}
